package com.zhenyi.toupiao.index;

import java.util.List;

import org.hashids.Hashids;

import com.cenjiawen.common.IndexController;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import com.toupiao.common.model.TpActivityVote;
import com.toupiao.common.model.TpJoin;
import com.toupiao.common.model.TpActivity;
import com.utils.AESUtils;
import com.utils.AuthUtils;
import com.zhenyi.toupiao.interceptor.AdminInterceptor;

import cn.hutool.core.date.DateUtil;

@Before(AdminInterceptor.class)
public class EditorController extends IndexController {

	private static int pageSize = 50;

	private final String AES_KEY = "toupiao@#$&*,.<>";
	
	protected Hashids hashids = new Hashids("toupiao", 4);
	
	@Clear
	public void index() {
		render("/toupiao/admin/index.html");
	}
	
	@Clear
	public void login() {
		String account = getPara("account");
		String password = getPara("password");
		try {
			password = AESUtils.decrypt(AES_KEY, password);
			if (password == null) {
				renderFailure();
				return;
			}
		} catch (Exception e) {
			renderFailure();
			return;
		}

		String defAccount = PropKit.get("TP_ADMIN_USER", "");
		String defPassword = PropKit.get("TP_ADMIN_PASSWORD", "");
		if (!StrKit.notBlank(defAccount, defPassword)) {
			renderFailure(500, "账号或密码不正确");
			return;
		}
		if (!defAccount.equals(account)) {
			renderFailure(500, "账号或密码不正确.");
			return;
		}
		if (!defPassword.equals(password)) {
			renderFailure(500, "账号或密码不正确 .");
			return;
		}
		String token = AuthUtils.login(account, this);
		renderSuccess(token);
	}
	
	public void logout() {
		renderFlag(AuthUtils.logout(this));
	}

	public void activities() {
		SqlPara sqlPara = Db.use("toupiao").getSqlPara("TPFindAllActivity");
		Page<TpActivity> list = TpActivity.dao.paginate(getPage(), pageSize, sqlPara);
		for (int i = 0; i < list.getList().size(); i ++) {
			TpActivity info = list.getList().get(i);
			info.put("link", "http://" + getRequest().getHeader("Host") + "/toupiao/" + info.getCode());
		}
		renderPage(list);
	}

	public void activityInfo() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpActivity info = TpActivity.dao.findById(id);
		if (info == null) {
			renderFailure(404, "activity not found");
			return;
		}
		renderResult(info);
	}

	public void submitActivity() {
		Long id = getParaToLong("id");
		Integer visitCount = getParaToInt("visitCount");
		Integer joinCount = getParaToInt("joinCount");
		Integer voteCount = getParaToInt("voteCount");
		String title = getPara("title");
		String desc = getPara("desc");
		String intro = getPara("intro");
		String content = getPara("content");
		String rule = getPara("rule");
		String buyRule = getPara("buyRule");
		String prize = getPara("prize");
		String banner = getPara("banner");
		String backgroundImage = getPara("backgroundImage");
		String notification = getPara("notification");
		String endTime = getPara("endTime");
		Integer votePerDay = getParaToInt("votePerDay");
		Integer votePerShop = getParaToInt("votePerShop");
		Integer votePerDiamond = getParaToInt("votePerDiamond");
		String shareTitle = getPara("shareTitle");
		String shareDesc = getPara("shareDesc");
		String shareImage = getPara("shareImage");
		
		boolean isNew = id == null;
		TpActivity info = isNew ? new TpActivity() : TpActivity.dao.findById(id);
		if (info == null) {
			renderFailure(404, "activity not found");
			return;
		}
		if (visitCount != null ) info.setVisitCount(visitCount);
		if (joinCount != null ) info.setJoinCount(joinCount);
		if (voteCount != null ) info.setVoteCount(voteCount);
		if (title != null ) info.setTitle(title);
		if (desc != null ) info.setDesc(desc);
		if (intro != null ) info.setIntro(intro);
		if (content != null ) info.setContent(content);
		if (rule != null ) info.setRule(rule);
		if (buyRule != null ) info.setBuyRule(buyRule);
		if (prize != null ) info.setPrize(prize);
		if (banner != null ) info.setBanner(banner);
		if (backgroundImage != null ) info.setBackgroundImage(backgroundImage);
		if (notification != null ) info.setNotification(notification);
		if (endTime != null ) info.setEndTime(DateUtil.parse(endTime));
		if (votePerDay != null ) info.setVotePerDay(votePerDay);
		if (votePerShop != null ) info.setVotePerShop(votePerShop);
		if (votePerDiamond != null ) info.setVotePerDiamond(votePerDiamond);
		if (shareTitle != null ) info.setShareTitle(shareTitle);
		if (shareDesc != null ) info.setShareDesc(shareDesc);
		if (shareImage != null ) info.setShareImage(shareImage);

		if (isNew) info.setAddTime();
		
		boolean flag = isNew ? info.save() : info.update();
		if (flag) {
			info.setCode(hashids.encode(info.getId()));
			info.update();
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	public void deleteActivity() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpActivity info = TpActivity.dao.findById(id);
		if (info == null) {
			renderFailure(404, "activity not found");
			return;
		}
		boolean flag = info.delete();
		if (flag) {
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	public void joins() {
		Long activityId = getParaToLong("activityId");
		if (activityId == null) {
			renderFailure(500, "activity id null");
			return;
		}
		SqlPara sqlPara = Db.use("toupiao").getSqlPara("TPFindActicityJoin", activityId);
		Page<TpJoin> list = TpJoin.dao.paginate(getPage(), pageSize, sqlPara);
		renderPage(list);
	}
	
	public void joinInfo() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpJoin info = TpJoin.dao.findById(id);
		if (info == null) {
			renderFailure(404, "join not found");
			return;
		}
		renderResult(info);
	}
	
	public void submitJoin() {
		Long id = getParaToLong("id");
		// Integer no = getParaToInt("no");
		Integer vote = getParaToInt("vote", 0);
		Integer position = getParaToInt("position", 0);
		Integer nextVote = getParaToInt("nextVote", 0);
		String address = getPara("address");
		String content = getPara("content");
		String images = getPara("images");
		String logo = getPara("logo");
		Long activityId = getParaToLong("activityId");
		Long userId = getParaToLong("userId", 0L);
		String title = getPara("title");
		String cover = getPara("cover");
		
		if (activityId == null) {
			renderFailure(500, "activity id is null");
			return;
		}
		TpActivity activity = TpActivity.dao.findById(activityId);
		if (activity == null) {
			renderFailure(404, "activity not found");
			return;
		}
		Integer index = activity.getIndex() == null ? 0 : activity.getIndex();
		
		boolean isNew = id == null;
		TpJoin info = isNew ? new TpJoin() : TpJoin.dao.findById(id);
		if (info == null) {
			renderFailure(404, "join not found");
			return;
		}
		info.setAddress(address);
		info.setContent(content);
		info.setImages(images);
		info.setLogo(logo);
		info.setActivityId(activityId);
		info.setTitle(title);
		info.setCover(cover);
		if (userId != null) {
			info.setUserId(userId);
		}
		if (isNew) {
			info.setVote(vote);
			info.setPosition(position);
			info.setNextVote(nextVote);
			info.setNo(index + 1);
			info.setAddTime();
		}
		
		boolean flag = isNew ? info.save() : info.update();
		if (flag) {
			if (isNew) {
				info.setCode(hashids.encode(info.getId()));
				info.update();
				
				SqlPara sqlPara = Db.use("toupiao").getSqlPara("TPFindActicityJoin", activityId);
				activity.setJoinCount(TpJoin.dao.find(sqlPara).size());
				activity.setIndex(index + 1);
				activity.update();
			}
			
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	public void updateVote() {
		Long id = getParaToLong("id");
		Integer vote = getParaToInt("vote");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpJoin join = TpJoin.dao.findById(id);
		if (join == null) {
			renderFailure(404, "join not found");
			return;
		}
		join.setVote(vote);
		boolean flag = join.update();
		if (flag) {
			doRanking(join.getActivityId());
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	public void deleteJoin() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpJoin info = TpJoin.dao.findById(id);
		if (info == null) {
			renderFailure(404, "join not found");
			return;
		}
		Long activityId = info.getActivityId();
		TpActivity activity = TpActivity.dao.findById(activityId);
		
		boolean flag = info.delete();
		if (flag) {
			if (activity != null) {
				SqlPara sqlPara = Db.use("toupiao").getSqlPara("TPFindActicityJoin", activityId);
				activity.setJoinCount(TpActivity.dao.find(sqlPara).size());
				activity.update();
				
				doRanking(activityId);
			}
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	private void doRanking(Long activityId) {
		// 统计投票
		TpActivity activity = TpActivity.dao.findById(activityId);
		SqlPara sqlPara1 = Db.use("toupiao").getSqlPara("TPFindActicityJoin", activity.getId());
		List<TpJoin> list = TpJoin.dao.find(sqlPara1);
		int count = 0;
		for (TpJoin join : list) {
			count += join.getVote();
		}
		activity.setVoteCount(count);
		activity.update();
		
		// 统计排名信息
		SqlPara sqlPara2 = Db.use("toupiao").getSqlPara("TPFindRank", activityId);
		List<TpJoin> items = TpJoin.dao.paginate(1, 50, sqlPara2).getList();
		int lastVote = 0;
		int position = 1;
		for (TpJoin tpJoin : items) {
			tpJoin.setPosition(position);
			int currentVote = tpJoin.getVote();
			if (position == 1) {
				tpJoin.setNextVote(0);
			} else {
				int nextVote = lastVote - currentVote;
				tpJoin.setNextVote(nextVote);
			}
			lastVote = currentVote;
			tpJoin.update();
			position++;
		}
	}
	
	public void activityVotes() {
		Long activityId = getParaToLong("activityId");
		if (activityId == null) {
			renderFailure(500, "activity id is null");
			return;
		}
		SqlPara sqlPara = Db.use("toupiao").getSqlPara("TPFindActicityVote", activityId);
		Page<TpActivityVote> page = TpActivityVote.dao.paginate(getPage(), pageSize, sqlPara);
		renderPage(page);
	}
	
	public void activityVoteInfo() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpActivityVote info = TpActivityVote.dao.findById(id);
		if (info == null) {
			renderFailure(404, "join not found");
			return;
		}
		renderResult(info);
		
	}
	
	public void submitActivityVote() {
		Long id = getParaToLong("id");
		Integer price = getParaToInt("price");
		Integer vote = getParaToInt("vote");
		Long activityId = getParaToLong("activityId");
		
		boolean isNew = id == null;
		TpActivityVote info = isNew ? new TpActivityVote() : TpActivityVote.dao.findById(id);
		info.setPrice(price);
		info.setVote(vote);
		info.setActivityId(activityId);
		
		boolean flag = isNew ? info.save() : info.update();
		if (flag) {
			renderSuccess();
		} else {
			renderFailure();
		}
	}
	
	public void deleteActivityVote() {
		Long id = getParaToLong("id");
		if (id == null) {
			renderFailure(500, "id is null");
			return;
		}
		TpActivityVote info = TpActivityVote.dao.findById(id);
		if (info == null) {
			renderFailure(404, "activity not found");
			return;
		}
		boolean flag = info.delete();
		if (flag) {
			renderSuccess();
		} else {
			renderFailure();
		}
		
	}

}
